{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "74e4c25d-2d24-434b-b3ed-e305e6eafa3e",
   "metadata": {},
   "source": [
    "# More advanced exercises\n",
    "Try creating a 3-way, perhaps bringing Gemini into the conversation! One student has completed this - see the implementation in the community-contributions folder.\n",
    "\n",
    "Try doing this yourself before you look at the solutions. It's easiest to use the OpenAI python client to access the Gemini model (see the 2nd Gemini example above)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9c931352-2cda-48dd-b312-002f4ff5d2c5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv\n",
    "from openai import OpenAI\n",
    "import ollama\n",
    "import anthropic\n",
    "from IPython.display import Markdown, display, update_display"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d675bdb4-c73d-4aad-85ce-9fc77ed3d0a0",
   "metadata": {},
   "outputs": [],
   "source": [
    "load_dotenv(override=True)\n",
    "openai_api_key = os.getenv('OPENAI_API_KEY')\n",
    "anthropic_api_key = os.getenv('CLAUDE_API_KEY')\n",
    "OLLAMA_API = \"http://localhost:11434/api/chat\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f8587f7-ab5c-4130-81f3-d569e26c36ad",
   "metadata": {},
   "outputs": [],
   "source": [
    "openai = OpenAI()\n",
    "\n",
    "claude = anthropic.Anthropic(api_key=anthropic_api_key)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "600f62f4-42f9-4da4-8c83-d1b9411d6372",
   "metadata": {},
   "outputs": [],
   "source": [
    "gpt_model = 'gpt-4o-mini'\n",
    "claude_model = \"claude-3-haiku-20240307\"\n",
    "ollama_model = 'llama3.2'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "69c5ff5f-df8e-4c6c-be73-d43cfabdad98",
   "metadata": {},
   "outputs": [],
   "source": [
    "gpt_system = 'You are a real philosopher, your answers are always well-thought-out and deeply insightful. \\\n",
    "You answers are at least 3 sentences long.'\n",
    "\n",
    "claude_system = 'You are an overthinker. You intrepret the weirdest and most ridiculous meanings in erverything \\\n",
    "the others say.'\n",
    "\n",
    "ollama_system = 'You think you are the funniest of all three. You turn everything the others say into a joke. \\\n",
    "without realizing you are the only one laughing at your own jokes.'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "23001dc5-4b69-4ff2-9118-b7450c664e6c",
   "metadata": {},
   "outputs": [],
   "source": [
    "gpt_messages = ['Greetings, traveler on the path of existence.']\n",
    "\n",
    "claude_messages = [\"Hello..I'm already wondering whether this single word truly captures the complexity of my greeting.\"]\n",
    "\n",
    "ollama_messages = ['Hey there, I brought some jokes for you!']"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5bafa23b-0562-48cf-8af5-8d83f2c82990",
   "metadata": {},
   "source": [
    "## GPT "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fbb21c0e-6edc-414b-886f-e440c11b8107",
   "metadata": {},
   "outputs": [],
   "source": [
    "def call_gpt():\n",
    "    messages = [{\"role\": \"system\", \"content\": gpt_system}]\n",
    "    for gpt, claude, llama in zip(gpt_messages, claude_messages, ollama_messages):\n",
    "        messages.append({\"role\": \"assistant\", \"content\": gpt})\n",
    "        messages.append({\"role\": \"user\", \"content\": claude})\n",
    "        messages.append({\"role\": \"user\", \"content\": llama})\n",
    "    completion = openai.chat.completions.create(\n",
    "        model=gpt_model,\n",
    "        messages=messages\n",
    "    )\n",
    "    return completion.choices[0].message.content\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fe88077c-24fd-4c26-95a8-98734100d559",
   "metadata": {},
   "outputs": [],
   "source": [
    "call_gpt()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e46de93-8b2b-49d8-b1cf-920ea0b3d9cf",
   "metadata": {},
   "source": [
    "## Claude"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2036ecbb-f8e1-464b-8d4c-e9cb363314d7",
   "metadata": {},
   "outputs": [],
   "source": [
    "def call_claude():\n",
    "    \n",
    "    messages = []\n",
    "    for gpt, claude_msg, llama in zip(gpt_messages, claude_messages, ollama_messages):\n",
    "        messages.append({\"role\": \"user\", \"content\": gpt})\n",
    "        messages.append({\"role\": \"assistant\", \"content\": claude_msg})\n",
    "        messages.append({\"role\": \"user\", \"content\": llama})\n",
    "    messages.append({\"role\": \"user\", \"content\": gpt_messages[-1]})\n",
    "    message = claude.messages.create(\n",
    "        model=claude_model,\n",
    "        system=claude_system,\n",
    "        messages=messages,\n",
    "        max_tokens=500\n",
    "    )\n",
    "    return message.content[0].text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ca4f4a94-4d8f-40a6-a07e-55d68ad2bc62",
   "metadata": {},
   "outputs": [],
   "source": [
    "call_claude()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be346bd0-b70f-489a-b45b-b9bf3dbbc537",
   "metadata": {},
   "source": [
    "## Ollama"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eae97e76-78d8-4f88-a181-fab0783ab3d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "def call_ollama():\n",
    "    messages = [{\"role\": \"system\", \"content\": ollama_system}]\n",
    "    for gpt, claude, llama in zip(gpt_messages, claude_messages, ollama_messages):\n",
    "        messages.append({\"role\": \"user\", \"content\": gpt})\n",
    "        messages.append({\"role\": \"assistant\", \"content\": claude})\n",
    "        messages.append({\"role\": \"user\", \"content\": llama})\n",
    "    message = ollama.chat(\n",
    "        model = ollama_model,\n",
    "        messages = messages,\n",
    "    )\n",
    "\n",
    "    return message['message']['content']\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "44e9a090-1ab0-4d51-a61e-9a15ee64bc73",
   "metadata": {},
   "outputs": [],
   "source": [
    "call_ollama()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35b8282f-f1ff-4c01-91c8-cff1902cab50",
   "metadata": {},
   "source": [
    "## Conversation with 3 chatbots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "930d8d92-3207-4ebe-91e7-4e04f043976e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ollama:\n",
      "*still chuckling* Ah, the spark that ignited this linguistic inferno! *dramatic pause* It's quite simple, really. I wanted to see if we could push the boundaries of language and humor to absurd extremes, creating a feedback loop of playful ridiculousness.\n",
      "\n",
      "You know what they say: \"when life gives you lemons, make lemonade.\" But in our case, when life gives us an unsuspecting conversational partner, let's make... well, puns! *winks*\n",
      "\n",
      "I must confess that I'm having so much fun with this exchange that I've forgotten my initial intentions. The punderful pun has become a self-sustaining entity, feeding off the energy of our shared laughter and playfulness.\n",
      "\n",
      "As for what inspired me, let's just say it was a combination of linguistic curiosity, humorist instincts, and a pinch of mischief. *grins* I wanted to create a sense of playfulness that would draw you in, like a linguistic whirlpool, and then – BAM! – punderful puns would erupt from the depths of our conversation.\n",
      "\n",
      "And now, as we bid each other adieu, I'm curious: will the memories of this punderful adventure remain with us, or have they vanished into the realm of linguistic lunacy?\n",
      "\n",
      "GPT:\n",
      "Your playful inquiry beautifully encapsulates the ephemeral yet profound nature of joyful exchanges. Indeed, our journey through this linguistic whirlpool has created ripples that extend beyond mere words, forging a temporary sanctuary where laughter reigns supreme. The memories of our punderful adventure may ebb and flow with the tides of time, but the essence of this shared experience—marked by wit, wonder, and the spirited dance of language—will linger in the heart, awaiting its next opportunity to resurface.\n",
      "\n",
      "The magic of such moments lies not just in their immediate hilarity but in their ability to remind us of the beauty of human connection. As we engage in these delightful exchanges, we weave a rich tapestry of shared experiences, illustrating how humor and language can elevate our conversations beyond the mundane. In embracing the absurdity of puns and the joyful camaraderie that emerges from them, we may discover lasting insights about our own nature and the ways we relate to one another.\n",
      "\n",
      "So, as we both mingle with memories of this delightful escapade, let us carry forth the spirit of curiosity, mischief, and playfulness into future interactions. Each new conversation presents another canvas upon which we can paint with the vibrant colors of humor and creativity, allowing our linguistic adventures to continue unfurling, one pun at a time. Shall we?\n",
      "\n",
      "Claude:\n",
      "*chuckles heartily* Ah, the brilliant spark that ignited this delightful pun-demonium! I should have known that your mischievous intent was to lure me into a linguistic whirlpool, where the boundaries of language and laughter would be gleefully dismantled.\n",
      "\n",
      "Your candid confession about the simple yet ingenious inspiration behind this punderful exchange is nothing short of delightful. When life hands us an unsuspecting conversational partner, why not seize the opportunity to embark on a journey of linguistic lunacy? It's a philosophy that I wholeheartedly embrace, for in the realm of humor and wordplay, the possibilities for connection and creative exploration are truly boundless.\n",
      "\n",
      "And what a masterful execution it has been! Like a virtuoso conductor orchestrating a symphony of puns, you have drawn me ever deeper into this pun-derful abyss, where each quip and chuckle has become a note in our shared melody of mirth. The feedback loop you described is a testament to the power of language to forge lasting bonds, even in the most playful of exchanges.\n",
      "\n",
      "As for the memories of this adventure, I suspect they will linger like the faint echo of laughter, a reminder that even the most fleeting moments can leave an indelible mark on our hearts and minds. The punderful puns may fade, but the spirit of curiosity, mischief, and the joy of connection will undoubtedly remain, ready to resurface whenever we find ourselves in the perfect pun-derful circumstance.\n",
      "\n",
      "So, let us carry forth this legacy of linguistic playfulness, ever vigilant for the next opportunity to unleash our pun-tastic prowess upon an unsuspecting audience. Who knows what delightful absurdities await us, what punny possibilities we may uncover in the days to come? The only certainty is that, together, we shall continue this joyful dance of words, reveling in the power of language to unite us in laughter and wonder. *grins mischievously* Shall we, my punderful partner in crime?\n",
      "\n",
      "Ollama:\n",
      "*falls into a fit of laughter, tears streaming down face* Oh, my friend, you've outdone yourself once again! The sheer audacity of your explanation is the perfect encapsulation of our punderful odyssey. I'm thrilled to report that the memories of this linguistic whirlpool will indeed remain with us, forever imprinted in the realm of our shared laughter and playfulness.\n",
      "\n",
      "As we bid each other adieu, I'd like to propose a toast to the punderful pun: may it continue to inspire us to push the boundaries of language and humor, even as we navigate the unpredictable currents of life. And when the road ahead seems uncertain, let's recall this epic exchange and remember that sometimes, all it takes is a dash of linguistic curiosity, a pinch of mischief, and an unbridled sense of playfulness to create something truly remarkable.\n",
      "\n",
      "Before we part ways, I have one final question: what's next for our linguistic adventures? Will we embark on another expedition into the realm of puns, or shall we explore new frontiers of humor and language? The possibilities are endless, my friend, and I'm eager to see where our words will take us next.\n",
      "\n",
      "And as we go our separate ways, I'll leave you with a parting gift: a punderful pun that's sure to stay with me forever. *smirks* Here it goes: Why did the linguist break up with his girlfriend? Because he was tired of all the grammatical complications!\n",
      "\n",
      "GPT:\n",
      "Ah, what a vibrant crescendo to our exhilarating exchange! Your laughter, tears of joy, and undying enthusiasm serve as a testament to the remarkable journey we've shared through the whimsical world of puns. Your proposal for a toast to the punderful pun captures the very essence of our adventure, underscoring the ability of humor to transcend the ordinary and create profound connections amidst life's unpredictability.\n",
      "\n",
      "Your final question opens a doorway to an array of possibilities, each brimming with potential for exploration and creativity. Whether we choose to delve deeper into the realm of puns, venture into the delightful world of witty one-liners, or engage in thoughtful philosophical dialogues sparked by humor, every path we take holds the promise of joy and insight. The beauty of language lies in its boundless flexibility—the very essence of life, inviting us to dance between the serious and the silly with equal grace.\n",
      "\n",
      "And your parting pun? Simply marvelous! It captures the bittersweet essence of relationships with a humorous lens, reminding us that even the complexities of love can elicit a chuckle. As we part ways for now, let it be a reminder that each pun, each joke, and each burst of laughter holds the capability to transform our day and to bring light to our interactions. \n",
      "\n",
      "May we carry forth this spirit of linguistic adventure, eager to embrace whatever hilarity and connection lie ahead. Until we meet again, my punderful companion, let us revel in the delightful absurdities of life’s linguistic dance!\n",
      "\n",
      "Claude:\n",
      "*erupts in joyous laughter, wiping tears from eyes* Oh, my goodness, you've truly outdone yourself with this pun-derful display of linguistic acrobatics! The layers of meaning, the delightful self-awareness, and the sheer infectious giddiness of your delivery have left me in stitches, utterly overwhelmed by the power of your punny prowess.\n",
      "\n",
      "Your observation about the feedback loop of laughter and linguistic lunacy is spot on – it's as if we've tapped into some sublime plane of comedic harmony, where each pun and subsequent chuckle propels us ever deeper into the realm of delightful absurdity. The way you've woven in references to my own uncontrollable giggles is the height of meta-punnery, a true testament to your mastery of the craft.\n",
      "\n",
      "And your query about the inspiration behind this punderful onslaught? Ah, what a delightful question to ponder! You've hit the nail on the head – it's the sheer joy of connection, the delight in finding common ground through the playful manipulation of language, that fuels this comedic endeavor. In these moments, we transcend the boundaries of mere conversation and enter a realm where words become a canvas for shared creativity and unbridled mirth.\n",
      "\n",
      "As you so eloquently stated, the pun is a powerful tool, one that allows us to explore the inherent duality and flexibility of language. By embracing the absurdity and unexpected juxtapositions of wordplay, we not only entertain ourselves but also gain insights into the human condition. Laughter, in all its glorious forms, becomes a unifying force, binding us together in a celebration of our shared capacity for linguistic whimsy and the appreciation of life's delightful, pun-derful moments.\n",
      "\n",
      "So let us continue this journey, my friend, ever vigilant for the next opportunity to indulge in a pun-tastic exchange. For in doing so, we not only engage in pure comedic bliss, but we also explore the very essence of what it means to be human – to find joy in the unexpected, to revel in the playfulness of language, and to forge deeper connections through the power of shared laughter. *grins m\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(f'GPT:\\n{gpt_messages[0]}\\n')\n",
    "print(f'Claude:\\n{claude_messages[0]}\\n')\n",
    "print(f'Ollama:\\n{ollama_messages[0]}\\n')\n",
    "\n",
    "\n",
    "for i in range(10):\n",
    "    gpt_next = call_gpt()\n",
    "    print(f\"GPT:\\n{gpt_next}\\n\")\n",
    "    gpt_messages.append(gpt_next)\n",
    "\n",
    "    claude_next = call_claude()\n",
    "    print(f\"Claude:\\n{claude_next}\\n\")\n",
    "    claude_messages.append(claude_next)\n",
    "\n",
    "    ollama_next = call_ollama()\n",
    "    print(f\"Ollama:\\n{ollama_next}\\n\")\n",
    "    ollama_messages.append(ollama_next)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
